home *** CD-ROM | disk | FTP | other *** search
/ Future Workshop / Future Workshop.iso / multimed / qtw111 / mplayer / framewnd.c < prev    next >
C/C++ Source or Header  |  1994-01-11  |  40KB  |  1,074 lines

  1.  
  2. // ---------------------------------------------------------------------
  3. //
  4. // FrameWnd.c - Movie Player - QuickTime for Windows
  5. //
  6. //              Version 1.0
  7. //
  8. //              (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
  9. //
  10. // ---------------------------------------------------------------------
  11.  
  12.  
  13. // Includes
  14. // --------
  15. #include <Windows.H>  // Required by Windows
  16. #include <commdlg.h>  // Header file for common dlgs
  17. #include <dlgs.h>     // Header file for common dlgs ids
  18. #include <cderr.h>    // Header file for error ids
  19. #include <memory.h>   // For memset()
  20. #include <shellapi.h> // Required for drag and drop
  21.  
  22. #include <qtole.h> // Interface to qtole dll's
  23.  
  24. #include "common.h" // Interface to common.c
  25.  
  26. #include "player.h"  // Interface to other *.c files
  27. #include "player.hr" // Defines used in *.rc files
  28.  
  29.  
  30. // Message-Persistent Data
  31. // -----------------------
  32. static struct // Hungarian notation: g
  33.   { HWND      hwndClient;          // MDI client window
  34.     WORD      wNumMovies;          // Number of movie wnds
  35.     BOOL      bUserAbortPrint;     // User abort print flag
  36.     HWND      hwndCancelPrt;       // Handle of print cancel dlg
  37.     HBITMAP   hAboutBitmap;        // Temp static storage of bitmap
  38.                                    // displayed in about dialogs
  39.     WORD      wTileCascadeArrange; // Indicates tiling, cascading or
  40.                                    // icon arrange
  41.     BOOL      bIconized;           // TRUE while frame wnd is iconized
  42.     BOOL      bRestoring;          // TRUE if restoring iconized frame wnd
  43.   } g;
  44.  
  45.  
  46. // Exported callback functions
  47. // ----------------------------
  48. BOOL __export CALLBACK AboutDlgProc       (HWND, UINT, WPARAM, LPARAM);
  49. BOOL __export CALLBACK CloseEnumProc      (HWND, LPARAM);
  50. BOOL __export CALLBACK MovieEnumProc      (HWND, LPARAM);
  51. BOOL __export CALLBACK PrintCancelDlgProc (HWND, UINT, WPARAM, LPARAM);
  52. int  __export CALLBACK PrintAbortProc     (HDC, int);
  53. UINT __export CALLBACK PrintDlgHookProc   (HWND, UINT, WPARAM, LPARAM);
  54.  
  55. // Internal Function Declarations
  56. // ------------------------------
  57. static LONG NEAR PlayerFrameCreate       (HWND);
  58. static LONG NEAR PlayerFileCommands      (HWND, WPARAM, WORD);
  59. static LONG NEAR PlayerWindowCommands    (HWND, WPARAM, WORD);
  60. static LONG NEAR PlayerHelpCommands      (HWND, WPARAM, WORD);
  61. static LONG NEAR LaunchMovieWnd          (LPSTR, LPSTR);
  62. static VOID NEAR PlayerEnableMenus       (HWND, BOOL);
  63. static VOID NEAR TellUserCommonDlgError  (DWORD);
  64. static LONG NEAR ProcessDroppedFiles     (HWND, WPARAM);
  65. static VOID NEAR DestroyHelpInstance     (HWND);
  66.  
  67. // -----------------------------------------------------------------------
  68.  
  69.  
  70. // Function: PlayerFrameWndProc - Player Frame Window Procedure
  71. // --------------------------------------------------------------------
  72. // Parameters: As required by Microsoft Windows
  73. //
  74. // Returns:    Via DefFrameProc
  75. // --------------------------------------------------------------------
  76. LONG __export CALLBACK PlayerFrameWndProc
  77.     (HWND hwndFrame, UINT message, WPARAM wParam, LPARAM lParam)
  78.  
  79. {
  80.     WNDENUMPROC       lpfnEnumMovies; // -> callback funcion for
  81.                                       // enumeration of movies
  82.     HWND              hwndMovie;      // Temp handle of active movie wnd
  83.     LPQTOLE_OLEDATA   lpOleData;      // -> ole data
  84.  
  85.     switch( message ) {
  86.         case WM_CREATE:
  87.             return PlayerFrameCreate( hwndFrame );
  88.  
  89.         case WM_PALETTECHANGED:
  90.             if( g.wNumMovies &&
  91.                 ( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
  92.                 ( (FARPROC) MovieEnumProc, PlayerQueryInstance()))) { // Tell the movie wnds to repaint
  93.                 EnumChildWindows( g.hwndClient, lpfnEnumMovies,
  94.                     (LPARAM) message);
  95.                 FreeProcInstance( (FARPROC) lpfnEnumMovies );
  96.             }
  97.  
  98.             return 0L;
  99.  
  100.         case WM_SIZE:
  101.             if( wParam == SIZE_MINIMIZED ) {
  102.                 g.bIconized  = TRUE;
  103.                 g.bRestoring = FALSE;
  104.             }
  105.             else if( g.bIconized && 
  106.                 (( wParam == SIZE_RESTORED ) ||
  107.                 ( wParam == SIZE_MAXIMIZED ))) {
  108.                 g.bIconized  = FALSE;
  109.                 g.bRestoring = TRUE;
  110.             }
  111.  
  112.             if( g.wNumMovies &&
  113.                 ( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
  114.                 ( (FARPROC) MovieEnumProc, PlayerQueryInstance()))) { // Tell the movie wnds to reset their grow box bounds rect
  115.                 EnumChildWindows( g.hwndClient, lpfnEnumMovies, 
  116.                     (LPARAM) message);
  117.                 FreeProcInstance( (FARPROC) lpfnEnumMovies );
  118.             }
  119.  
  120.             if( g.bRestoring ) {
  121.                 g.bRestoring = FALSE;
  122.             }
  123.  
  124.             break; // break to DefFrameProc
  125.  
  126.  
  127.         case WM_INITMENUPOPUP:
  128.             // Set check marks and enable menu items in popups
  129.             if( !(BOOL) HIWORD( lParam ) &&
  130.                 ( hwndMovie = (HWND) SendMessage
  131.                 ( g.hwndClient, WM_MDIGETACTIVE, 0, 0l )) &&
  132.                 IsWindow( hwndMovie ))
  133.                 SendMessage( hwndMovie, WM_PLAYER_INITPOPUPS, wParam, lParam );
  134.  
  135.             return 0L;
  136.  
  137.         case WM_COMMAND:
  138.             switch( wParam ) {
  139.                 case PLAYER_FILE_OPEN: // file menu popup
  140.                 case PLAYER_FILE_CLOSE:
  141.                 case PLAYER_FILE_PRTSETUP:
  142.                 case PLAYER_FILE_PRINT:
  143.                 case PLAYER_FILE_EXIT:
  144.                     return PlayerFileCommands
  145.                         ( hwndFrame, wParam, HIWORD (lParam));
  146.  
  147.                 case PLAYER_WINDOW_TILE: // window menu popup
  148.                 case PLAYER_WINDOW_CASCADE:
  149.                 case PLAYER_WINDOW_ARRANGE:
  150.                     return PlayerWindowCommands
  151.                         ( hwndFrame, wParam, HIWORD (lParam));
  152.  
  153.  
  154.                 case PLAYER_HELP_PLAYERHELP: // help menu popup
  155.                 case PLAYER_HELP_USINGHELP:
  156.                 case PLAYER_HELP_ABOUTPLAYER:
  157.                     return PlayerHelpCommands
  158.                         ( hwndFrame, wParam, HIWORD( lParam ));
  159.  
  160.                 default:
  161.                     if( ( hwndMovie = (HWND) SendMessage
  162.                         ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  163.                         IsWindow( hwndMovie ))
  164.                         SendMessage( hwndMovie, WM_COMMAND, wParam, lParam );
  165.  
  166.                     break; // break to DefFrameProc
  167.             } 
  168.  
  169.             break;
  170.  
  171.         // WM_USER messages
  172.  
  173.         case WM_PLAYER_CMDLINE:
  174.             return LaunchMovieWnd( (LPSTR) lParam, NULL );
  175.  
  176.         case WM_PLAYER_MOVIEDELETED:
  177.             // Decrement movie count. This is incremented in LaunchMovieWnd
  178.             // when movie is created
  179.             if( --g.wNumMovies <= 0 )
  180.                 PlayerEnableMenus( hwndFrame, FALSE );
  181.             return 0L;
  182.  
  183.         // These next messages are posted by the ole callback function in MovieUtl.c
  184.         case WM_PLAYER_OLE_OPTIONSDLG:
  185.             PlayerGetOptions( NULL, (LPQTOLE_OPTIONSMOVIE) lParam );
  186.             return 0L;
  187.  
  188.         case WM_PLAYER_OLE_PLAYOBJECT:
  189.             QTOLE_PlayObject( PlayerQueryOleData(), lParam );
  190.             return 0L;
  191.  
  192.         // end WM_USER messages
  193.  
  194.  
  195.         // Standard drag and drop processing. Allows for multiple movies but
  196.         // does not worry about position of drop
  197.         case WM_DROPFILES:
  198.             return ProcessDroppedFiles( hwndFrame, wParam );
  199.  
  200.         case WM_QUERYENDSESSION:
  201.         case WM_CLOSE:
  202.             if( g.wNumMovies &&
  203.                 ( lpfnEnumMovies = (WNDENUMPROC) MakeProcInstance
  204.                 ( (FARPROC) CloseEnumProc, PlayerQueryInstance()))) { // Give all movies a chance to stop the close
  205.                 EnumChildWindows( g.hwndClient, lpfnEnumMovies, 0L );
  206.                 FreeProcInstance( (FARPROC) lpfnEnumMovies );
  207.  
  208.                 // If someone didn't want to close, don't kill the app
  209.                 if( NULL != GetWindow( g.hwndClient, GW_CHILD ))
  210.                     return 0L;
  211.             }
  212.  
  213.             // Tell qtole.dll that we are closing the server
  214.             // Don't close if QTOLE_ClossingServerWnd returns FALSE;
  215.             if( ( lpOleData = PlayerQueryOleData()) && 
  216.                 lpOleData->lpqtoleServer &&
  217.                 !QTOLE_ClosingServerWnd( lpOleData, message ))
  218.                 return 0L;
  219.  
  220.             break; // break to DefFrameProc
  221.  
  222.         case WM_DESTROY:
  223.             DragAcceptFiles( hwndFrame, FALSE );
  224.  
  225.             // Destroy help instance
  226.             DestroyHelpInstance( hwndFrame );
  227.  
  228.             // NULL the hwnd globals in playmain.c
  229.             PlayerNoMoreWindow();
  230.  
  231.             PostQuitMessage( 0 );
  232.             break;
  233.  
  234.     }
  235.  
  236.     return DefFrameProc
  237.         ( hwndFrame, g.hwndClient, message, wParam, lParam );
  238. }
  239.  
  240.  
  241. // Function: PlayerFrameCreate - process WM_CREATE message
  242. // --------------------------------------------------------------------
  243. // Parameters: HWND hwndFrame;         Frame window
  244. //
  245. // Returns:    0L if OK, else returns -1L to kill app
  246. // --------------------------------------------------------------------
  247. static LONG NEAR PlayerFrameCreate( HWND hwndFrame )
  248.  
  249. {
  250.     CLIENTCREATESTRUCT  clientcreate;  // MDI client create struct
  251.     char                szCaption[50]; // caption buffer;
  252.  
  253.  
  254.     szCaption[0] = '\0';
  255.     if( LoadString( PlayerQueryResources(), PLAYER_STRING_CAPTION,
  256.         szCaption, sizeof( szCaption )))
  257.         SetWindowText( hwndFrame, szCaption );
  258.     // No point in trying for an error message here since it probably won't
  259.     // load either.
  260.  
  261.     // disable menu items until a movie is created
  262.     g.wNumMovies = 0;
  263.     PlayerEnableMenus( hwndFrame, FALSE );
  264.  
  265.     DragAcceptFiles( hwndFrame, TRUE );
  266.  
  267.     clientcreate.hWindowMenu =
  268.         GetSubMenu( GetMenu( hwndFrame ), MENU_WINDOW_POS );
  269.     clientcreate.idFirstChild = PLAYER_CLIENT_FIRSTCHILD;
  270.  
  271.     if( !(g.hwndClient = CreateWindow("MDICLIENT", NULL,
  272.         WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
  273.         WS_HSCROLL | WS_VSCROLL,
  274.         0, 0, 0, 0, hwndFrame, ( HMENU) 1,
  275.         PlayerQueryInstance(), (LPVOID) &clientcreate )))
  276.         return -1L; // return -1 to kill app
  277.     else
  278.         return  0L;
  279. }
  280.  
  281.  
  282. // Function: PlayerFileCommands - Process WM_COMMAND, File popup messages
  283. // --------------------------------------------------------------------
  284. // Parameters: HWND   hwndFrame;      Frame window
  285. //             WORD   wIDItem;        Menu or control id
  286. //             WORD   wNotifyCode;    notification message
  287. //
  288. // Returns:    LONG   generally 0L
  289. // --------------------------------------------------------------------
  290. static LONG NEAR PlayerFileCommands
  291.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  292.  
  293. {
  294.     HWND           hwndMovie;                 // Handle of movie window
  295.     OPENFILENAME   ofn;                       // OPENFILENAME struct
  296.     UINT           cbString;                  // Length of filter string
  297.     char           szMoviePath[256];          // Movie file path
  298.                                               // Must be at least 256 bytes
  299.     char           szMovieName[MAX_NAME_LEN]; // Movie file name
  300.     char           szFilter[256];             // Movie file filter str
  301.     LPSTR          lpTemp;                    // Temp -> to string
  302.     LPSTR          lpSave;                    // Temp -> to string
  303.     char           chReplace;                 // String separator used in filter string
  304.     DWORD          dwError;                   // Common dlg error return
  305.     PRINTDLG       pd;                        // Print common dlg struct
  306.     ABORTPROC      lpPrintAbortProc;          // Print abort proc
  307.     DLGPROC        lpPrtCancelProc;           // Print cancel dlg proc
  308.     WORD           wIDError;                  // Resource errror string id
  309.     int            nError;                    // Error return;
  310.  
  311.     static DWORD   nFilterIndex;
  312.  
  313.  
  314.     typedef UINT ( CALLBACK * PRINTDLGHOOKPROC ) ( HWND, UINT, WPARAM, LPARAM );
  315.  
  316.  
  317.     switch( wIDItem ) {
  318.         case PLAYER_FILE_OPEN:
  319.             memset( &ofn, 0, sizeof( OPENFILENAME ));
  320.             szMoviePath[0] = '\0';
  321.  
  322.             if( !(cbString = LoadString( PlayerQueryResources(),
  323.                 PLAYER_STRING_OPENMOVIEFILTER,
  324.                 szFilter, sizeof( szFilter ))))
  325.                 return 0L;
  326.  
  327.             // See 3.1 SDK manuals, vol. 1 for examples of common dlg processing
  328.             lpTemp = szFilter + lstrlen( szFilter );
  329.             chReplace = *AnsiPrev( szFilter, lpTemp );
  330.             lpTemp = szFilter;
  331.             while( *lpTemp ) {
  332.                 if( *lpTemp == chReplace ) { // Need to increment pointer past chReplace before
  333.                                              // setting to NULL. Otherwise AnsiNext thinks it is
  334.                                              // at end of string and quits
  335.                     lpSave = lpTemp;
  336.                     lpTemp = AnsiNext( lpTemp );
  337.                     *lpSave = '\0';
  338.                 }
  339.                 else
  340.                     lpTemp = AnsiNext( lpTemp );
  341.             }
  342.  
  343.             ofn.lStructSize    = sizeof( OPENFILENAME );
  344.             ofn.hwndOwner      = hwndFrame;
  345.             ofn.lpstrFilter    = szFilter;
  346.             ofn.nFilterIndex   = nFilterIndex;
  347.             ofn.lpstrFile      = szMoviePath;
  348.             ofn.nMaxFile       = sizeof( szMoviePath );
  349.             ofn.lpstrFileTitle = szMovieName;
  350.             ofn.nMaxFileTitle  = sizeof( szMovieName );
  351.             ofn.Flags          = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |
  352.                 OFN_HIDEREADONLY;
  353.  
  354.             if( GetOpenFileName( &ofn )) {
  355.                 nFilterIndex = ofn.nFilterIndex;
  356.                 LaunchMovieWnd( szMoviePath, szMovieName );
  357.             }  
  358.             else if( dwError = CommDlgExtendedError() ) { // Tell the user about the error
  359.                 TellUserCommonDlgError( dwError );
  360.             }
  361.  
  362.             return 0L;
  363.  
  364.         case PLAYER_FILE_CLOSE:
  365.             if( ( hwndMovie = (HWND) SendMessage
  366.                 ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  367.                 IsWindow( hwndMovie ))
  368.                 SendMessage( hwndMovie, WM_CLOSE, 0, 0L );
  369.  
  370.             return 0L;
  371.  
  372.         case PLAYER_FILE_PRTSETUP:
  373.             memset( &pd, 0, sizeof( PRINTDLG ));
  374.  
  375.             pd.lStructSize = sizeof( PRINTDLG );
  376.             pd.hwndOwner   = hwndFrame;
  377.             pd.Flags       = PD_PRINTSETUP;
  378.  
  379.             if( ( PrintDlg( &pd ) == 0 ) &&
  380.                 ( dwError = CommDlgExtendedError() )) { // Tell the user about the error
  381.                 TellUserCommonDlgError( dwError );
  382.             }
  383.  
  384.             return 0L;
  385.  
  386.         case PLAYER_FILE_PRINT:
  387.             memset( &pd, 0, sizeof( PRINTDLG ));
  388.  
  389.             pd.lStructSize = sizeof( PRINTDLG );
  390.             pd.hwndOwner   = hwndFrame;
  391.             pd.Flags       = PD_RETURNDC |
  392.                 PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE;
  393.             pd.hInstance   = PlayerQueryResources();
  394.             pd.lpPrintTemplateName = MAKEINTRESOURCE( CUSTOM_DLG_COMN_PRINT );
  395.             if( !( pd.lpfnPrintHook =  (PRINTDLGHOOKPROC) 
  396.                 MakeProcInstance( (FARPROC) PrintDlgHookProc,
  397.                 PlayerQueryInstance()))) {
  398.                 CommonTellUser( PlayerQueryResources(), 
  399.                     PLAYER_STRING_NOMEMORY, NULL, MB_OK );
  400.                 return 0L;
  401.             }
  402.  
  403.             if( PrintDlg( &pd ) != 0 ) {
  404.                 lpPrtCancelProc = (DLGPROC) MakeProcInstance
  405.                     ( (FARPROC) PrintCancelDlgProc, PlayerQueryInstance() );
  406.  
  407.                 lpPrintAbortProc = (ABORTPROC) MakeProcInstance
  408.                     ( (FARPROC) PrintAbortProc, PlayerQueryInstance() );
  409.  
  410.                 if( !lpPrtCancelProc || !lpPrintAbortProc ) {
  411.                     CommonTellUser( PlayerQueryResources(),
  412.                         PLAYER_STRING_NOMEMORY, NULL, MB_OK );
  413.                     return 0L;
  414.                 }
  415.  
  416.                 g.bUserAbortPrint = FALSE;
  417.                 nError   = 0;
  418.                 wIDError = 0;
  419.  
  420.                 if( !(g.hwndCancelPrt =
  421.                     CreateDialog( PlayerQueryResources(),
  422.                     MAKEINTRESOURCE( PLAYER_DLG_PRINTCANCEL ),
  423.                     hwndFrame, lpPrtCancelProc ))) {
  424.                     wIDError = PLAYER_STRING_CANCELDLG;
  425.                 }
  426.                 else {
  427.                     EnableWindow( hwndFrame, FALSE ); // disable frame window
  428.                     if( SetAbortProc( pd.hDC, lpPrintAbortProc ) <= 0 )
  429.                         wIDError = PLAYER_STRING_ABORTPROC;
  430.                     else {
  431.                         if( hwndMovie = (HWND) SendMessage
  432.                             ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L ))
  433.                             nError = (int) SendMessage( hwndMovie,
  434.                             WM_PLAYER_PRINTFRAME, 0,
  435.                             (LPARAM) (LPPRINTDLG) &pd );
  436.                         if( ( nError < 0 ) &&
  437.                             ( nError & SP_NOTREPORTED ) &&
  438.                             !g.bUserAbortPrint ) {
  439.                             switch( nError ) {
  440.                                 case SP_APPABORT:
  441.                                 case SP_USERABORT:
  442.                                     break;
  443.                                 case SP_OUTOFDISK:
  444.                                     wIDError = PLAYER_STRING_PRT_OUTOFDISK;
  445.                                     break;
  446.                                 case SP_OUTOFMEMORY:
  447.                                     wIDError = PLAYER_STRING_PRT_NOMEMORY;
  448.                                     break;
  449.                                 case SP_ERROR: // fall through
  450.                                 default:
  451.                                     wIDError = PLAYER_STRING_PRT_GENERROR;
  452.                                     break;
  453.                             }
  454.                         }
  455.                     }
  456.  
  457.                     EnableWindow( hwndFrame, TRUE ); // reenable frame window
  458.  
  459.                     if( g.hwndCancelPrt )
  460.                         DestroyWindow( g.hwndCancelPrt );
  461.                 }
  462.  
  463.                 if( wIDError )
  464.                     CommonTellUser( PlayerQueryResources(), wIDError,
  465.                     PLAYER_STRING_PRT_CAPTION, MB_OK );
  466.  
  467.                 FreeProcInstance( (FARPROC) lpPrtCancelProc );
  468.                 FreeProcInstance( (FARPROC) lpPrintAbortProc );
  469.  
  470.                 if( pd.hDC != NULL )
  471.                     DeleteDC( pd.hDC );
  472.                 if( pd.hDevMode != NULL )
  473.                     GlobalFree( pd.hDevMode );
  474.                 if( pd.hDevNames != NULL )
  475.                     GlobalFree( pd.hDevNames );
  476.  
  477.             }
  478.             else if( dwError = CommDlgExtendedError() ) { // Tell the user about the error
  479.                 TellUserCommonDlgError( dwError );
  480.             }
  481.  
  482.             return 0L;
  483.  
  484.         case PLAYER_FILE_EXIT:
  485.             SendMessage( hwndFrame, WM_CLOSE, 0, 0L );
  486.             return 0L;
  487.     }
  488.  
  489.     return 0L; // should never get here
  490.  
  491. }
  492.  
  493.  
  494. // Function: PlayerWindowCommands - Process WM_COMMAND, Window popup messages
  495. // --------------------------------------------------------------------
  496. // Parameters: HWND   hwndFrame;      Frame window
  497. //             WORD   wIDItem;        Menu or control id
  498. //             WORD   wNotifyCode;    notification message
  499. //
  500. // Returns:    LONG   generally 0L
  501. // --------------------------------------------------------------------
  502. static LONG NEAR PlayerWindowCommands
  503.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  504.  
  505. // Tile and cascade are implemented using modifications of
  506. // the standard MDI processing in order to preserve the size
  507. // and aspect ratio of the movies. The modifications are implemented
  508. // in MovieWnd.c on the basis of the value of g.wTileCascadeArrange
  509.  
  510. {
  511.     g.wTileCascadeArrange = wIDItem;
  512.  
  513.     switch( wIDItem ) { // Modify the tile using the WM_WINDOWPOSCHANGING message in 
  514.                         // the movie window processing to set the original aspect
  515.                         // ratio and, if possible, size of the movies
  516.         case PLAYER_WINDOW_TILE:
  517.             SendMessage( g.hwndClient, WM_MDITILE, 0, 0L );
  518.             break;
  519.  
  520.         // Modify the cascade using the WM_GETMINMAXINFO message in 
  521.         // the movie window processing to preserve the current size
  522.         // of the movies
  523.         case PLAYER_WINDOW_CASCADE:
  524.             SendMessage( g.hwndClient, WM_MDICASCADE, 0, 0L );
  525.             break;
  526.  
  527.         // This is standard MDI. 
  528.         case PLAYER_WINDOW_ARRANGE:
  529.             SendMessage( g.hwndClient, WM_MDIICONARRANGE, 0, 0L );
  530.             break;
  531.     }
  532.  
  533.     g.wTileCascadeArrange = 0;
  534.  
  535.     return 0L; 
  536.  
  537. }
  538.  
  539.  
  540. // Function: PlayerHelpCommands - Process WM_COMMAND, Help popup messages
  541. // --------------------------------------------------------------------
  542. // Parameters: HWND   hwndFrame;      Frame window
  543. //             WORD   wIDItem;        Menu or control id
  544. //             WORD   wNotifyCode;    notification message
  545. //
  546. // Returns:    LONG   generally 0L
  547. // --------------------------------------------------------------------
  548. static LONG NEAR PlayerHelpCommands
  549.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  550.  
  551. {
  552.     char       szHelp[MAX_PATH_LEN]; // Help file path
  553.     DLGPROC    lpDlgProc;            // -> dialog proc
  554.  
  555.     switch( wIDItem ) {
  556.         case PLAYER_HELP_PLAYERHELP:
  557.             CommonGetLocalizedHelpFile
  558.                 ( PLAYER_ROOT_NAME, szHelp, PlayerQueryInstance() );
  559.  
  560.             if( szHelp[0] )
  561.                 WinHelp( hwndFrame, (LPCSTR) szHelp, HELP_CONTENTS, 0L );
  562.             else
  563.                 CommonTellUser( PlayerQueryResources(),
  564.                 PLAYER_STRING_NOHELPFILE,
  565.                 PLAYER_STRING_CAPTION, MB_OK );
  566.  
  567.             return 0L;
  568.  
  569.         case PLAYER_HELP_USINGHELP:
  570.             WinHelp( hwndFrame, "WINHELP.HLP", HELP_CONTENTS, 0L );
  571.             return 0L;
  572.  
  573.         case PLAYER_HELP_ABOUTPLAYER:
  574.             if( ( g.hAboutBitmap = LoadBitmap( PlayerQueryResources(),
  575.                 MAKEINTRESOURCE( PLAYER_PLAYER_BITMAP ))) &&
  576.                 ( lpDlgProc = (DLGPROC) MakeProcInstance
  577.                 ( (FARPROC) AboutDlgProc, PlayerQueryInstance()))) {
  578.                 DialogBox( PlayerQueryResources(),
  579.                     MAKEINTRESOURCE( PLAYER_DLG_ABOUTPLAYER ),
  580.                     hwndFrame, lpDlgProc );
  581.                 FreeProcInstance( (FARPROC) lpDlgProc );
  582.             }
  583.             else
  584.                 CommonTellUser( PlayerQueryResources(),
  585.                 PLAYER_STRING_NOMEMORY,
  586.                 PLAYER_STRING_CAPTION, MB_OK );
  587.             if( g.hAboutBitmap )
  588.                 DeleteObject( g.hAboutBitmap );
  589.             g.hAboutBitmap = NULL;
  590.  
  591.             return 0L;
  592.     }
  593.  
  594.     return 0L; // should never get here
  595.  
  596. }
  597.  
  598. //// the following are some utility routines
  599.  
  600. // Function: CloseEnumProc - Close all enumerate proc
  601. // --------------------------------------------------------------------
  602. // Parameters: As required by Microsoft Windows
  603. //
  604. // Returns:    Always TRUE to enumerate all windows
  605. // --------------------------------------------------------------------
  606. BOOL __export CALLBACK CloseEnumProc( HWND hwnd, LPARAM lParam )
  607.  
  608. {
  609.     char   szClassName[40]; // Temp buffer for class name
  610.  
  611.     // Check class name since there are several classes of child windows
  612.     if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  613.         lstrcmpi( szClassName, PLAYER_MOVIE_CLASS ))
  614.         return TRUE;
  615.  
  616.     // If  someone doesn't want to close, stop enumeration
  617.     if( !SendMessage( hwnd, WM_QUERYENDSESSION, 0, 0L ))
  618.         return FALSE;
  619.  
  620.     SendMessage( GetParent( hwnd ), WM_MDIDESTROY, (WPARAM) hwnd, 0L );
  621.  
  622.     return TRUE;
  623. }
  624.  
  625. // Function: MovieEnumProc - Tells all movie wnds to do something
  626. // --------------------------------------------------------------------
  627. // Parameters: As required by Microsoft Windows
  628. //
  629. // Returns:    Always TRUE to enumerate all windows
  630. // --------------------------------------------------------------------
  631. BOOL __export CALLBACK MovieEnumProc( HWND hwnd, LPARAM lParam )
  632.  
  633. {
  634.     char    szClassName[40]; // Temp buffer for class name
  635.  
  636.     // Check class name since there are several classes of child windows
  637.     if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  638.         lstrcmpi( szClassName, PLAYER_MOVIE_CLASS ))
  639.         return TRUE;
  640.  
  641.     if( LOWORD( lParam ) == WM_PALETTECHANGED )
  642.         // Tell the movies to repaint. The background is fixed up in the
  643.         // paint processing
  644.         InvalidateRect( hwnd, NULL, FALSE );
  645.     else if( LOWORD( lParam ) == WM_SIZE ) {
  646.         SendMessage( hwnd, WM_PLAYER_UPDATEGBBOUNDSRECT, 0, 0L );
  647.         // Tell movies to stop if we are iconizing and to restart
  648.         // if restoring
  649.         if( g.bIconized || g.bRestoring )
  650.             SendMessage( hwnd, WM_PLAYER_PLAYTHEMOVIE,
  651.             (WPARAM ) g.bRestoring, 0L );
  652.     }
  653.  
  654.     return TRUE;
  655. }
  656.  
  657.  
  658. // Function: LaunchMovieWnd - tell hwndClient to launch a movie wnd
  659. // --------------------------------------------------------------------
  660. // Parameters: LPSTR     lpMoviePath      Path of movie file
  661. //             LPSTR     lpName           File name of movie file
  662. //
  663. // Returns:    LONG    0L if OK, else nonzero
  664. // --------------------------------------------------------------------
  665. static LONG NEAR LaunchMovieWnd( LPSTR lpMoviePath, LPSTR lpName )
  666.  
  667. {
  668.     MDICREATESTRUCT    mdicreate; // mdi create struct
  669.     HWND               hwndMovie; // Temp handle of window
  670.  
  671.     if( !lpMoviePath[0] )
  672.         return -1L;
  673.  
  674.     if( lpName == NULL ) {
  675.         lpName = lpMoviePath + lstrlen( lpMoviePath );
  676.         lpName = AnsiPrev( lpMoviePath, lpName );
  677.         while( *lpName && (*lpName != '\\') && (lpName != lpMoviePath))
  678.             lpName = AnsiPrev( lpMoviePath, lpName );
  679.         if( *lpName == '\\' )
  680.             lpName = AnsiNext( lpName );
  681.     }
  682.  
  683.     mdicreate.szClass = PLAYER_MOVIE_CLASS;
  684.     mdicreate.szTitle = AnsiLower( lpName );
  685.     mdicreate.hOwner  = PlayerQueryInstance();
  686.     mdicreate.x       = CW_USEDEFAULT;
  687.     mdicreate.y       = CW_USEDEFAULT;
  688.     mdicreate.cx      = CW_USEDEFAULT;
  689.     mdicreate.cy      = CW_USEDEFAULT;
  690.     mdicreate.style   = 0;
  691.     mdicreate.lParam  = (LPARAM) lpMoviePath;
  692.  
  693.     if( !( hwndMovie = (HWND) SendMessage
  694.         ( g.hwndClient, WM_MDICREATE, 0,
  695.         (LPARAM) (LPMDICREATESTRUCT) &mdicreate ))) {
  696.         return -1L;
  697.     }
  698.     else {
  699.         if(++g.wNumMovies == 1 )
  700.             PlayerEnableMenus( PlayerQueryFrameWindow(), TRUE );
  701.         return 0L;
  702.     }
  703. }
  704.  
  705. // Function: ProcessDroppedFiles - Process the WM_DROPFILES message
  706. // --------------------------------------------------------------------
  707. // Parameters: HWND     hwndFrame         Frame window handle
  708. //             WPARAM   wParam            Message wParam
  709. //
  710. // Returns:    LONG     Always 0L;
  711. // --------------------------------------------------------------------
  712. static LONG NEAR ProcessDroppedFiles( HWND hwndFrame, WPARAM wParam )
  713.  
  714. {
  715.     int           i;                        // Temp counter
  716.     int           nNumFiles;                // Temp number of dropped files
  717.     UINT          uBytes;                   // Temp len of drop file path
  718.     char          szDropFile[MAX_PATH_LEN]; // Temp drop file path
  719.  
  720.     if( nNumFiles = DragQueryFile( (HDROP) wParam, 0xffff,
  721.         (LPSTR) NULL, 0 )) { // Create processing requires that frame window has
  722.                              // nonzero dimensions so first restore iconized wnd
  723.         if( IsIconic( hwndFrame ))
  724.             ShowWindow( hwndFrame, SW_SHOWNORMAL );
  725.  
  726.         for( i=0; i < nNumFiles; i++ ) {
  727.             uBytes = DragQueryFile( (HDROP) wParam, i,
  728.                 (LPSTR) szDropFile, sizeof( szDropFile ));
  729.             if( uBytes > 0 )
  730.                 LaunchMovieWnd( szDropFile, NULL );
  731.         }
  732.     }
  733.  
  734.     DragFinish( (HDROP) wParam );
  735.  
  736.     return 0L;
  737. }
  738.  
  739.  
  740. // Function: DestroyHelpInstance - Tell windows that instance is done with
  741. //                                 help. This is called as a function so that
  742. //                                 szHelp[] is not an automatic var. in the
  743. //                                 winproc
  744. // --------------------------------------------------------------------
  745. // Parameters: HWND     hwndFrame         Frame window handle
  746. //
  747. // Returns:    VOID
  748. // --------------------------------------------------------------------
  749. static VOID NEAR DestroyHelpInstance( HWND hwndFrame )
  750.  
  751. {
  752.     char    szHelp[MAX_PATH_LEN]; // Help file name
  753.  
  754.     WinHelp( hwndFrame, CommonGetLocalizedHelpFile
  755.         ( PLAYER_ROOT_NAME, szHelp, PlayerQueryResources() ),
  756.         HELP_QUIT, NULL );
  757.     return;
  758. }
  759.  
  760.  
  761. // Function: AboutDlgProc - About dialog proc
  762. // --------------------------------------------------------------------
  763. // Parameters: As required by Microsoft Windows
  764. //
  765. // Returns:    As required by Microsoft Windows
  766. // --------------------------------------------------------------------
  767. BOOL __export CALLBACK AboutDlgProc
  768.     ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  769.  
  770. {
  771.     BITMAP       bm;          // Temp bitmap struct
  772.     HWND         hwndCntrl;   // Handle of rect control that is painted
  773.     HDC          hdestDC;     // hdc of control rect
  774.     HDC          hmemDC;      // Memory dc
  775.     RECT         rcdestRect;  // Rect of control
  776.     HBITMAP      hbitmapSave; // Prev bitmap
  777.     PAINTSTRUCT  ps;          // Paint struct
  778.  
  779.     switch( msg ) {
  780.         case WM_COMMAND:
  781.             EndDialog( hdlg, 0 );
  782.             return TRUE;
  783.  
  784.         case WM_PAINT:
  785.             // Don't bother with error messages since only effect is that
  786.             // bitmap will not appear in dialog
  787.             if( !BeginPaint( hdlg, &ps ))
  788.                 return FALSE;
  789.             EndPaint( hdlg, &ps );
  790.  
  791.             if( !g.hAboutBitmap ||
  792.                 !( hwndCntrl = GetDlgItem( hdlg, PLAYER_ABOUT_BMPFRAME )))
  793.                 return FALSE;
  794.  
  795.             InvalidateRect( hwndCntrl, NULL, TRUE );
  796.             UpdateWindow( hwndCntrl );
  797.  
  798.             if( !(hdestDC = GetDC( hwndCntrl )))
  799.                 return FALSE;
  800.  
  801.             if( hmemDC = CreateCompatibleDC( hdestDC )) {
  802.                 if( hbitmapSave = SelectObject( hmemDC, g.hAboutBitmap )) {
  803.                     GetObject( g.hAboutBitmap, sizeof( BITMAP ), &bm );
  804.                     GetClientRect( hwndCntrl, &rcdestRect );
  805.  
  806.                     BitBlt( hdestDC,
  807.                         ( rcdestRect.right - bm.bmWidth ) / 2,
  808.                         ( rcdestRect.bottom - bm.bmHeight ) / 2,
  809.                         bm.bmWidth, bm.bmHeight, hmemDC, 0, 0, SRCCOPY );
  810.  
  811.                     SelectObject( hmemDC, hbitmapSave );
  812.                 }
  813.  
  814.                 DeleteDC( hmemDC );
  815.             } 
  816.  
  817.             ReleaseDC( hwndCntrl, hdestDC );
  818.  
  819.             return FALSE;
  820.  
  821.         default:
  822.             return FALSE;
  823.     }
  824.  
  825.     return FALSE;
  826. }
  827.  
  828.  
  829. // Function: PrintAbortProc - Print abort proc
  830. // --------------------------------------------------------------------
  831. // Parameters: As required by Microsoft Windows
  832. //
  833. // Returns:    As required by Microsoft Windows
  834. // --------------------------------------------------------------------
  835. int __export CALLBACK PrintAbortProc( HDC hdc, int nCode )
  836.  
  837. {
  838.     MSG     msg; // Message struct
  839.  
  840.     while( !g.bUserAbortPrint &&
  841.         PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE )) {
  842.         if( !g.hwndCancelPrt ||
  843.             !IsDialogMessage( g.hwndCancelPrt, &msg )) {
  844.             TranslateMessage( &msg );
  845.             DispatchMessage( &msg );
  846.         }
  847.     }
  848.  
  849.     return !g.bUserAbortPrint;
  850. }
  851.  
  852. // Function: PrintCancelDlgProc - User cancel printing dlg proc
  853. // --------------------------------------------------------------------
  854. // Parameters: As required by Microsoft Windows
  855. //
  856. // Returns:    As required by Microsoft Windows
  857. // --------------------------------------------------------------------
  858. BOOL __export CALLBACK PrintCancelDlgProc
  859.     ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  860.  
  861. {
  862.     char    szName[MAX_NAME_LEN + 1]; // Buffer for movie name
  863.  
  864.     switch( msg ) {
  865.         case WM_INITDIALOG:
  866.             SetFocus( GetDlgItem( hdlg, IDCANCEL ));
  867.             SetDlgItemText( hdlg, PRINT_CANCEL_MOVIENAME,
  868.                 PlayerQueryActiveMovieName( szName ));
  869.             return TRUE;
  870.  
  871.         case WM_COMMAND:
  872.             return ( g.bUserAbortPrint = TRUE );
  873.  
  874.         case WM_DESTROY:
  875.             g.hwndCancelPrt = NULL;
  876.             break;
  877.     }
  878.  
  879.     return FALSE;
  880. }
  881.  
  882. // Function: PrintDlgHookProc - Custom print common dlg hook function
  883. // --------------------------------------------------------------------
  884. // Parameters: As required by Microsoft Windows
  885. //
  886. // Returns:    As required by Microsoft Windows
  887. // --------------------------------------------------------------------
  888. UINT __export CALLBACK PrintDlgHookProc
  889.                 (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
  890.  
  891. { // The dialog ids are defined in dlgs.h
  892.   // Array of ids of controls to be hidden
  893.     static int nIDs[] = {grp1, rad1, rad2, rad3, stc2, edt1, 
  894.                          stc3, edt2, chx1, chx2, pshHelp };
  895.     UINT   i; // Temp counter
  896.  
  897.  
  898.     if( message == WM_INITDIALOG ) {
  899.         for( i=0; i < ( sizeof( nIDs ) / sizeof( nIDs[0] )); i++ )
  900.             ShowWindow( GetDlgItem( hdlg, nIDs[i] ), SW_HIDE );
  901.  
  902.         return TRUE;
  903.     }
  904.     else
  905.         return FALSE;
  906. }
  907.  
  908.  
  909. // Function: PlayerEnableMenus - Disables menu items when there
  910. //                               are no movies
  911. // --------------------------------------------------------------------
  912. // Parameters: HWND       hwndFrame      Handle of frame window
  913. //             BOOL       bEnable        Enabling flag
  914. //
  915. // Returns:    VOID
  916. // --------------------------------------------------------------------
  917. static VOID NEAR PlayerEnableMenus( HWND hwndFrame, BOOL bEnable )
  918.  
  919. {
  920.     UINT    fFlag;      // Temp enabling flag
  921.     HMENU   hmenuFrame; // Handle to main menu of frame window
  922.     UINT    i;          // Index
  923.  
  924.     static UINT uMenuIDs[] = {PLAYER_FILE_CLOSE,
  925.                               PLAYER_FILE_PRINT,
  926.  
  927.                               PLAYER_EDIT_COPY,
  928.                               PLAYER_EDIT_OPTIONS,
  929.                               PLAYER_EDIT_CANCELSEL,
  930.  
  931.                               PLAYER_MOVIE_GETINFO,
  932.                               PLAYER_MOVIE_STOPATEND,
  933.                               PLAYER_MOVIE_LOOP,
  934.                               PLAYER_MOVIE_BACKANDFORTH,
  935.                               PLAYER_MOVIE_PLAYSELONLY,
  936.                               PLAYER_MOVIE_HALFSIZE,
  937.                               PLAYER_MOVIE_NORMALSIZE,
  938.                               PLAYER_MOVIE_DOUBLESIZE,
  939.                               PLAYER_MOVIE_SHOWPOSTER,
  940.  
  941.                               PLAYER_WINDOW_TILE,
  942.                               PLAYER_WINDOW_CASCADE,
  943.                               PLAYER_WINDOW_ARRANGE
  944.                              };
  945.  
  946.  
  947.     if( !( hmenuFrame = GetMenu( hwndFrame )))
  948.         return;
  949.  
  950.     fFlag = (bEnable ? MF_ENABLED : MF_GRAYED ) | MF_BYCOMMAND;
  951.     for( i=0; i < sizeof( uMenuIDs ) / sizeof( uMenuIDs[0] ); i++ )
  952.         EnableMenuItem( hmenuFrame, uMenuIDs[i], fFlag );
  953.  
  954.     DrawMenuBar( hwndFrame );
  955.  
  956.     return;
  957. }
  958.  
  959. // Function: TellUserCommonDlgError - Tell the user about the common dlg
  960. //                                    error
  961. // --------------------------------------------------------------------
  962. // Parameters: DWORD       dwError      error code returned by common dlg
  963. //
  964. // Returns:    VOID
  965. // --------------------------------------------------------------------
  966. static VOID NEAR TellUserCommonDlgError( DWORD dwError )
  967.  
  968. {
  969.     WORD          wIDErrorString; // String id
  970.  
  971.     // Not much here now, can make this as explicit as desired
  972.     // Now returns text of error id, i.e. "CDERR_INITIALIZATION"
  973.     // Not all messages are explicitly included
  974.  
  975.     switch( dwError ) {
  976.         case CDERR_FINDRESFAILURE: 
  977.             wIDErrorString = PLAYER_STRING_CDLG_FINDRESFAIL;
  978.             break;
  979.         case CDERR_INITIALIZATION:
  980.             wIDErrorString = PLAYER_STRING_CDLG_INITFAIL;
  981.             break;
  982.         case CDERR_LOADRESFAILURE:
  983.             wIDErrorString = PLAYER_STRING_CDLG_LOADRESFAIL;
  984.             break;           
  985.         case CDERR_LOCKRESFAILURE:
  986.             wIDErrorString = PLAYER_STRING_CDLG_LOCKRESFAIL;
  987.             break;
  988.         case CDERR_MEMALLOCFAILURE:
  989.             wIDErrorString = PLAYER_STRING_CDLG_MEMALLOCFAIL;
  990.             break;
  991.         case CDERR_MEMLOCKFAILURE:
  992.             wIDErrorString = PLAYER_STRING_CDLG_MEMLOCKFAIL;
  993.             break;
  994.         case CDERR_STRUCTSIZE:
  995.             wIDErrorString = PLAYER_STRING_CDLG_STRUCTSIZE;
  996.             break;
  997.         case FNERR_INVALIDFILENAME:
  998.             wIDErrorString = PLAYER_STRING_CDLG_BADFILENAME;
  999.             break;
  1000.         case PDERR_INITFAILURE:
  1001.             wIDErrorString = PLAYER_STRING_CDLG_PRTINITFAIL;
  1002.             break;
  1003.         case PDERR_LOADDRVFAILURE:
  1004.             wIDErrorString = PLAYER_STRING_CDLG_LOADDRVFAIL;
  1005.             break;
  1006.         case PDERR_NODEFAULTPRN:
  1007.             wIDErrorString = PLAYER_STRING_CDLG_NODEFPRINTER;
  1008.             break;
  1009.         case PDERR_NODEVICES:
  1010.             wIDErrorString = PLAYER_STRING_CDLG_NODEVICES;
  1011.             break;
  1012.         case PDERR_PRINTERNOTFOUND:
  1013.             wIDErrorString = PLAYER_STRING_CDLG_NOFINDPNTR;
  1014.             break;
  1015.         case PDERR_SETUPFAILURE:
  1016.             wIDErrorString = PLAYER_STRING_CDLG_SETUPFAIL;
  1017.             break;
  1018.         default:
  1019.             wIDErrorString = PLAYER_STRING_CDLG_GENFAILURE;
  1020.             break;
  1021.     }
  1022.  
  1023.     if( wIDErrorString == PLAYER_STRING_CDLG_GENFAILURE )
  1024.         CommonTellUser( PlayerQueryResources(),
  1025.         PLAYER_STRING_CDLG_GENFAILURE,
  1026.         PLAYER_STRING_CDLG_CAP, MB_OK, dwError );
  1027.     else
  1028.         CommonTellUser( PlayerQueryResources(),
  1029.         PLAYER_STRING_CDLG_FORMAT, PLAYER_STRING_CDLG_CAP,
  1030.         MB_OK, wIDErrorString );
  1031.     return;
  1032.  
  1033. }
  1034.  
  1035.  
  1036. //  The remaining functions are the query functions called by other modules
  1037.  
  1038. // Function: PlayerQueryClientWindow - Query Client Window Handle
  1039. // --------------------------------------------------------------------
  1040. // Parameters: None.
  1041. //
  1042. // Returns:    HWND g.hwndClient;        MDI client window handle
  1043. // --------------------------------------------------------------------
  1044. HWND FAR PlayerQueryClientWindow( VOID )
  1045.  
  1046. {
  1047.     return g.hwndClient;
  1048. }
  1049.  
  1050. // Function: PlayerQueryNumMovies - Query number of movies
  1051. // --------------------------------------------------------------------
  1052. // Parameters: None.
  1053. //
  1054. // Returns:    HWND g.wNumMovies;        Number of movies
  1055. // --------------------------------------------------------------------
  1056. WORD FAR PlayerQueryNumMovies( VOID )
  1057.  
  1058. {
  1059.     return g.wNumMovies;
  1060. }
  1061.  
  1062. // Function: PlayerQueryMDIAction - Query tile, cascade or icon arrange.
  1063. // --------------------------------------------------------------------
  1064. // Parameters: None.
  1065. //
  1066. // Returns:    WORD   wTileCascadeArrange    MDI action menu id
  1067. // --------------------------------------------------------------------
  1068. WORD FAR PlayerQueryMDIAction( VOID )
  1069.  
  1070. {
  1071.     return g.wTileCascadeArrange;
  1072. }
  1073.  
  1074.